Functions used in the program help reduce the program’s size as multiple calls to a function causes the execution of the same set of instructions which appears only once in the memory without any duplication. However, each time a function called, it involves substantial execution time overheads for tasks such as storing memory address of the instruction following the function call, saving values of registers, pushing actual arguments onto the stack and passing control to the function where the arguments of the called function are popped (removed) from the stack. Then the body of function executes. If there is any return statement, the value returned to the calling program. Finally, the control transferred back to the calling program. All these overheads increase the execution time and consequently reduces the efficiency of the program.
In the case of functions containing large code lines, the execution time overheads cost can be compromised with the huge amount of memory saved. But in the case of functions containing few instructions, there is little saving in memory space, although the execution time overheads remain as that of a large function.
Whenever a function invoked, a set of operations performed, including passing the control from the calling function to the called function, managing stack for arguments and return values, managing registers, etc. All these operations take much of compiler time and slow down the execution process. This overhead can be avoided by using macros in a program. However, macros not considered true functions, as they do not perform type checking. Another way to make function calls execute faster and perform type checking is to make the function inline.
One solution to this problem is to replace each function call with the necessary code instead of making a function. It improves the execution time as there is no transfer of control but using the same repeated code in the program suffers from the advantages of functions such as modularity, understand ability etc. Any modification will also cause problems. So to take the benefits of functions and at the same time improve the execution time in case of small functions, C++ provides another type of function known as Inline function.
An inline function is a function whose code is copied in place of each function call. In other words, inline functions are those functions whose function body inserted in the function call during the compilation process. Thus, there is no transfer of control between the calling and the called function that results in removing the function call overheads, which in tum improves the execution time.
Inline functions can declare by prefixing the keyword inline to the return type in the function prototype. An inline function ‘requests’ the compiler to replace each call by the code in its body. Specifying a function as inline is just a request to the compiler and not a command. So, it does not change the behaviour of a function. Moreover, the compiler may or may not choose to replace each call with the body. In case it does, the function becomes ‘in line’ with the rest of the source code.
Functions made inline normally when they are small and contain only a few lines of code. The use of the inline function improves the program’s execution speed, and there is not much increase in the size of the program as it is a small function. As the function grows in size, the execution time benefits of inline functions become very costly. An inline function containing large code lines still provides execution time benefits, but due to the huge wastage of memory of the program, these execution time benefits seem small. In such cases, the use of the normal function recommended.
An inline function definition is similar to the normal function except that the keyword inline specified before the function’s return type in the function definition. The syntax for defining inline function is
inline ret_type func_name(parameter_list) { function body }
The inline function should always be defined before the main() function so that the inline function definition must be visible for the compiler to inline a function at the point of the call. So, there is no need to specify the function prototype (or function declaration).
#include<iostream~h> #include<conio.h> inline int max(int x,int y) { return(x>y?x:y); } int main() { clrscr(); int m = 10,n = 25; int a,b; a = max(6,8); cout<<"Greatest of 6 and 8 = "<<a; b=max(m,n); cout<<"\nGreatest of m = "<<m<<" and n = "<<n<<" is "<<b; getch(); return 0; } Output : Greatest of 6 and 8 = 8 Greatest of m = 10 and n = 25 is 25
Explanation: In the above program, the inline function max () used to calculate the maximum of two integer numbers. On compilation, the statement a=max (6, 8); invokes the inline function max(), and the body of the inline function is expanded inline at the point of call, i.e. a=6>8?6: 8. Similarly, it expands the other function call statement.
Here, the statements written in the inline function max () inserted at each place without any transfer of control between the calling and the called function. Finally, when we execute the program, we get the desired result.
An Inline specification in the function is only a request and not a command to the compiler. However, the compiler may ignore the request and treat the inline function as a normal function under the following situations.
• If the function body contains many statements like a switch or goto or looping statements such as while, do-while, etc.
• If a function contains static variables.
• If the function is recursive because it cannot be expanded entirely at the point of its call.
We’ll be covering the following topics in this tutorial:
Advantage of Inline Functions
1. Its use reduces the execution time because the body of the inline function inserted at each point of an inline function call, and hence there are no function call overheads as in the case of normal functions.
2. They provide strong type checking compared to macros, where no type checking performed at all.
3. Improves the program readability and modularity as it possesses functions with reduced execution time.
The disadvantage of Inline Functions
1. All functions that use the inline function must be recompiled if any changes made to the inline function.
2. Although the inline function reduces the execution time, it increases the executable file’s size as multiple copies of the inline function’s body inserted in the program. So it is always commended to use inline functions for small frequently used functions.
3. The definition of the inline function should appear before the function call.
A difference between a normal function call and inline function call is shown in Figure
In Figure, when the compiler reads the statement prod (a, b), it transfers the control to the prod () function. However, in Figure, the prod ( ) function is declared as an inline function. As a result, when the compiler reads the statement prod (a, b), it replaces the function call with the definition of the prod ( ) function.
Inline functions are ideal for functions that are small in size and frequently used by the programs. This is because inline functions reduce the time consumption and overhead involved in function calls. However, they also significantly increase the memory size of the program because each occurrence of inline function call is replaced by its code, which in turn may adversely affect the readability of the program. Also, these functions restrict the portability of the program.
Difference Between Inline Functions and Macros
Inline functions replace the use of # defines macros of C language. Macros in C are expanded by the preprocessor, whereas inline functions are expanded inline in the program during compilation. In the case of inline functions, strong type checking occurs, so there are no side effects caused by missing brackets or by double substitution of a parameter as in the case of macros. It can illustrated in the following program.
#include<iostream.h> #include<conio.h> #define ADD(x) x + x inline int add(int x) { return(x+x); } int main() { clrscr (); int a = 2,m; m = ADD(++a);//calling macro cout<<"a = "<<a<<" m = "<<m; a = 2; m = add(++a); //calling inline function cout<<"\na = "<<a<<" m = "<<m; getch(); return 0; } Output: a = 4 m = 8 a = 3 m = 6
Explanation: The macro ADD is expanded as m = ++x + ++x; during preprocessing. The output clears that macros’ use creates side effects as the variable (a) increments twice even though we have used the increment operator only once. But in the inline function, the argument is incremented only once, and hence there is no side effect. It is because argument types checked, and necessary conversions are performed correctly by the inline function.
The following table enlists the differences between inline functions and macros.
Inline Function | Macros |
1. It is a function provided by C++. | 1. It is a preprocessor directive provided by C. |
2. It is declared by using the keyword inline before the function declarator. | 2. It is declared by using the preprocessor directive #define before the actual statement. |
3. Expressions passed as arguments to inline functions are evaluated only once. | 3. In some cases, expressions passed as arguments to macros can be evaluated more than once. Every time you use an argument in a macro, that argument is evaluated. |
4. The compiler processes inline functions at com pile time. | 4. They are expanded by the preprocessor at pre-compile time. |
5. Inline functions follow all the protocols(rules) of data type safety enforced on normal functions. Arguments types are checked, and necessary conversions are performed correctly. | 5. The main disadvantage of macros is the lack of type checking leading to high level of type security. No error checking is done during compilation. E.g. You can pass strings to a macro that does some integer arithmetic. #define MIN(x,y) ((x>y)?y:x) int main() { cout<<“Minimum of 15 and 25 = “<< MIN(“15″ ,”25”)<<endl; return 0; The above macro on execution gives unexpected result. |
6. Inline functions may or may not be expanded by the compiler. It is the complier’s decision whether to expand the function inline or not. | 6. Macros are always expanded. |
7. It can be defined inside or outside the class. | 7. It cannot be defined inside the class. |
8. Inline function can access the class’s data member. | 8. The preprocessor has no permission to access data member of a class and are thus useless even if used within a class. |